package com.dyh.quickdemo.demos.EnhanceFc;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.function.Function;

/*
@Author=Joey Wheeler
@Date=2020/10/26 14:24
*/
@Setter@Getter@AllArgsConstructor
public class FuncEnhancerFail<T,R> {

    private Function<T,R> core;

    public FuncEnhancerFail<T,R> withTimeoutFallback(Function<T,R> fallBack, long limitMilliseconds, ExecutorService executor){
        /*替换掉core*/
        this.core = t->{
            R r = null;
            try {
                Future<R> coreFuture=executor.submit(()->core.apply(t));
                r = coreFuture.get(limitMilliseconds, TimeUnit.MILLISECONDS);
            } catch (TimeoutException e) {
                r = fallBack.apply(t);
            }
            catch (Exception e){
                /**/
            }
            return r;
        };
        return this;
    }

    public FuncEnhancerFail<T,R> withInterceptors(final Function<T,R>... interceptors){
        return withInterceptors(Arrays.asList(interceptors));
    }

    public FuncEnhancerFail<T,R> withInterceptors(final List<Function<T,R>> interceptors){

        if (interceptors == null){
            //do nothing
        }
        else {
            this.core = t -> {
                R r = null;
                for (Function<T, R> interceptor : interceptors) {
                    r = interceptor.apply(t);
                    if (r!=null)//拦截到
                        return r;
                }
                r = core.apply(t);
                return r;
            };
        }
        return this;
    }

    public Function<T,R> enchance(){
        return this.core;
    }

    public static void main(String[] args) throws InterruptedException {
        Function<String,String> core = s -> {

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return s+"!";
        };

        Function<String,String> fuckInspector = s -> {
            if (s.contains("fuck"))
                return "冚家铲";
            return null;
        };

        Function<String,String> timeOutFallBack = s -> "超时";

        Function<String,String> enchanceFunc = new FuncEnhancerFail<>(core)
                .withInterceptors(fuckInspector).
                withTimeoutFallback(timeOutFallBack,1000, ForkJoinPool.commonPool())
                .enchance();

        String res = enchanceFunc.apply("11");
        System.out.println(res);

        Thread.sleep(5000);

    }
}
